Microsoft DirectX 8.1 (C++)

Writing Tolls

This topic applies to Windows XP Home Edition and Windows XP Professional only.

This section describes how to write a conditional access toll.

Payments

Toll payments are made through the ICAToll::PayToll method. The details of making the payment, including verification and security issues, depend entirely on the implementation. Usually, the toll provides a UI for the user to enter passwords, credit card numbers, or other information.

For a toll that blocks a denial, successful payment means the toll must remove the denial. Call the ICADenial::get_DeniedObject method to retrieve the denied object, and use that object to obtain the denials collection. The get_DeniedObject method returns an IUnknown pointer, because the tolled object can be a request, a component, or another toll. Each of these objects supports a get_Denials method, which returns the denials collection. Query for the appropriate interface, call get_Denials, and then call ICADenials::Remove to remove the denial. The following example shows how to remove a denial from a request:

// Retrieve the request object.
CComPtr<IUnknown> pRequestUnk;
m_pDenial->get_DeniedObject(&pRequestUnk);
CComQIPtr<ICARequest> pRequest(pRequestUnk);
if (pRequest)
{
    // Remove the denial from the denials collection.
    CComPtr<ICADenials> pDenials;
    pRequest->get_Denials(&pDenials);
    CComQIPtr<IUnknown> pDenialUnk(pDenial);
    CComVariant cv(pDenialUnk);  // The Remove method takes a VT_UNKNOWN.
    pDenials->Remove(cv);
}

Before the denials collection actually removes the denial, it verifies that it has permission to do so by calling the ICAPolicy::get_OkToRemoveDenial method. The policy should return TRUE. (By this point, presumably the toll has processed the payment.)

For a toll that applies to an offer, successful payment means that the owning policy should store a record of the payment. Later, when the user requests the program that he or she purchased, the policy must allow the request. Note that other policies might still deny the request. In that case, the policy should provide a refund.

Paid Tolls

The CA Manager maintains a collection of paid tolls. The toll should move itself—or a version of itself—into this collection. When the CA Manager unloads, it saves the paid tolls collection to storage. The toll must support persistence through one of the following interfaces: IPersistStream, IPersistStorage, or IPersistPropertyBag. The paid tolls collection enables the user to view a history of the tolls he or she has paid, and possibly refund tolls.

Refunds

The user refunds a toll through the ICAToll::RefundToll method, which the toll must implement. The toll must determine whether a refund is valid. By the time RefundToll is called, there may no longer be an instance of the owning policy, especially in the case of a filter policy. The toll should be able to process the refund itself, or create a temporary instance of the policy.

Secondary Denials

Adding a secondary denial to a toll works in the same way as adding a denial to a request. The only difference is that the toll cannot use CoCreateInstance to create its own denials collection. Instead, the denials collection is created automatically when the policy first adds the toll to its parent collection. The toll retrieves its own denials collection by calling the ICAManager::get_DenialsFor method. For more information, see ICAToll::get_Denials.